home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 05 / 6 / DISK0564.ZIP / SOURCE.ARC / HEAD.ASM < prev    next >
Assembly Source File  |  1989-01-19  |  11KB  |  411 lines

  1.         TITLE HEAD - A FILTER FOR MSDOS2
  2.         PAGE 55,132
  3. ;******************************************************************************
  4. ;       THIS PROGRAM PRINTS THE FIRST FEW LINES OF A TEXT FILE.
  5. ;
  6. ;       IT READS FROM A FILE IF SPECIFIED, OR FROM THE STANDARD INPUT OTHERWISE
  7. ;       IT WRITES TO THE STANDARD OUTPUT.
  8. ;
  9. ;       USAGE:  HEAD -n file1 file2 ...
  10. ;               -n is optional, limits output to n lines (20 default)
  11. ;        file names can be ambiguous
  12. ;
  13. ;
  14. ;    VERSION 1.8, 02-OCT-87: assembles under MASM 5.0
  15. ;    VERSION 1.7, 21-DEC-86: now supports wildcards, multiple files
  16. ;    VERSION 1.6, 06-SEP-86: minor cleanup, fixed bug involving failure
  17. ;                to set data segment when reading from stdin.
  18. ;    VERSION 1.5, 13-AUG-86: handles arbitrary -n (up to 65535)
  19. ;                also now buffers output, doesn't expand tabs
  20. ;    VERSION 1.4, 06-JUL-86: changes to memory allocation, now assembles
  21. ;                under MASM 4.0
  22. ;       VERSION 1,3, 04-FEB-86: fixed bug in reading from std. input
  23. ;       VERSION 1.2, 16-JAN-86: makes UTIL and CONSOLE external modules
  24. ;       VERSION 1.1, 27-SEP-85: defaults to std. input if no file given
  25. ;       VERSION 1.0, 19-SEP-85
  26. ;
  27. ;       BY: JON DART
  28. ;           3012 HAWTHORN ST.,
  29. ;           SAN DIEGO, CA 92104
  30. ;
  31. ;       TO BUILD HEAD EXE:
  32. ;
  33. ;    MASM HEAD,HEAD,NUL,NUL
  34. ;    LINK HEAD,HEAD,NUL,ASM 
  35.  
  36. INBUFSIZE EQU   8192                    ;SIZE OF INPUT BUFFER
  37. OUTBUFSIZE EQU    512            ;SIZE OF OUTPUT BUFFER
  38. MAXARGS EQU    40            ;MAX. # CMD. LINE ARGUMENTS
  39. PRGSIZE EQU    1000H            ;MAX. SIZE OF CODE + FIXED DATA
  40. M       EQU     BYTE PTR 0[BX]
  41.  
  42.         .XLIST
  43.         INCLUDE ASCII.DEF
  44.         INCLUDE MSDOS2.DEF
  45.     INCLUDE MACROS.DEF
  46.         .LIST
  47.  
  48.     DOSSEG
  49.     .MODEL    SMALL
  50.  
  51. ;       MEMORY DEFINITIONS:
  52. ;
  53.     .DATA
  54. INHANDLE DW     0                       ;INPUT FILE HANDLE
  55.                                         ;(DEFAULTS TO STD. INPUT)
  56. NUMARGS DW    1            ;NUMBER OF COMMAND LINE ARGUMENTS
  57. OUTNDX    DW    0            ;OFFSET TO NEXT SLOT IN OUTPUT BUFFER
  58. NUMLIN  DW      20                      ;NUMBER OF LINES TO LIST
  59. ONEFILE    DB    1            ;SET 1 IF ONE UNAMBIG. ARGUMENT        
  60. MSG1    DB      CR,LF,"head: can't open ",0
  61. MSG1E   DB      CR,LF,0
  62. MSG2    DB      CR,LF,"head: read error on file ",0
  63. MSG4    DB    CR,LF,"head usage: head -n filename",CR,LF,0
  64. MSG5    DB    CR,LF,"head: too many command line arguments",CR,LF,0
  65. MSG6    DB    CR,LF,"head: unknown pathname ",0
  66.  
  67. ;    UNINITIALIZED DATA SPACE:
  68.  
  69.     .DATA?
  70. INBUF   DB      INBUFSIZE DUP (?)       ;INPUT BUFFER
  71. OUTBUF    DB      OUTBUFSIZE DUP (?)    ;OUTPUT BUFFER
  72. ARGPTRS DB    (2*MAXARGS) DUP (?)    ;POINTERS TO ARGUMENTS
  73. ARGBUF  DB    512 DUP (?)         ;ARGUMENT BUFFER    
  74. SPATH    DB    65 DUP (?)        ;SEARCH PATH
  75. PREFIX    DB      65 DUP (?)        ;SEARCH PREFIX
  76. FILENAME DB    65 DUP (?)        ;COMPOSITE FILE NAME (PREFIX + NAME)
  77. DTA    DB    128 DUP (?)        ;DTA  AREA
  78. MAXMEM    EQU    DTA + 128        ;MAX. MEMORY USED
  79.  
  80.     .STACK
  81.         DB 512 DUP (?)
  82.  
  83.     .CODE
  84.         EXTRN   COUT:NEAR,ERRORMSG:NEAR
  85.         EXTRN   SKIPSP:NEAR,DTOBIN:NEAR,CPYCNT:NEAR,TYPTX:NEAR
  86.     EXTRN    FIXPATH:NEAR,GETARGS:NEAR
  87.     EXTRN    TYPE_UNK:ABS,TYPE_UFN:ABS
  88.  
  89. ENTRY:
  90.         TEST_DOS2                       ;TEST FOR DOS 2.0, EXIT IF DOS 1
  91. MEMOK:  
  92.     MOV     AX,DGROUP
  93.     MOV    ES,AX            ;SET EXTRA SEG TO POINT TO BUFFERS
  94.         MOV     BX,80H                ;GET BYTE COUNT FOR COMMAND LINE
  95.         CMP     BYTE PTR [BX],0         ;TEST IT
  96.         JNE     L_1                     ;IF NOT 0
  97.         JMP     START            ;NO ARGUMENTS, USE STDIN
  98. L_1:
  99.         PUSH    BX
  100.         MOV     DL,BYTE PTR [BX]
  101.         MOV     DH,0
  102.         ADD     BX,DX
  103.         INC     BX
  104.         MOV     BYTE PTR [BX],0         ;PUT 0 BYTE AT END OF COMMAND LINE
  105.         POP     BX
  106.         INC     BX            ;POINT TO START OF COMMAND LINE
  107.     MOV    SI,OFFSET ARGPTRS
  108.     MOV    DI,OFFSET ARGBUF
  109.     MOV    CX,MAXARGS
  110.     CALL    GETARGS            ;COLLECT COMMAND LINE ARGUMENTS
  111.     JNB    L_2            ;IF OK
  112.         MOV     AX,DGROUP
  113.         MOV     DS,AX
  114.         MOV     DX,OFFSET MSG5
  115.         CALL    ERRORMSG                ;TOO MANY ARGUMENTS
  116.         JMP     EXIT2
  117. L_2:
  118.     MOV    AX,DGROUP
  119.     MOV    DS,AX            ;SET DATA SEG TO FIXED DATA
  120.     MOV    WORD PTR NUMARGS,CX    ;SAVE # OF ARGUMENTS
  121.     CMP    CX,0
  122.     JNE    L_2A            ;IF SOME ARGUMENT
  123.     JMP    START            ;NO ARGUMENTS, USE STDIN
  124. L_2A:
  125.     MOV    SI,OFFSET ARGPTRS
  126.     MOV    BX,WORD PTR [SI]    ;POINT TO 1ST ARGUMENT
  127.     MOV    AL,BYTE PTR [BX]    ;GET 1ST CHAR.
  128.         CMP     AL,'-'
  129.         JE      L_3                     ;IF SWITCH SPECIFIED
  130.     MOV    SI,OFFSET ARGPTRS
  131.     MOV    CX,WORD PTR NUMARGS    ;GET # OF ARGUMENTS
  132.         JMP     GETFILES
  133. L_3:
  134.         INC     BX
  135.         MOV     CL,0
  136.         PUSH    BX
  137. CD:     MOV     AL,BYTE PTR [BX]         ;HAVE NUMBER, COUNT NUMBER OF DIGITS
  138.         CMP     AL,'0'
  139.         JC      NODGT
  140.         CMP     AL,'9'+1
  141.         JNC     NODGT
  142.         INC     BX
  143.         INC     CL
  144.         JMP     SHORT CD
  145. NODGT:
  146.         POP     BX
  147.         MOV     CH,0                    ;CL HOLDS DIGIT COUNT
  148.         CALL    DTOBIN                  ;CONVERT NUMBER TO BINARY
  149.         JNC     L_4                     ;IF OK
  150.     JMP    SHORT USE
  151. L_4:
  152.         CMP     AX,0                    ;IS NUMBER 0?
  153.         JNE     NOT0                    ;NO.
  154.         JMP     EXIT2                   ;YES, IT IS, JUST EXIT
  155. NOT0:
  156.         MOV     WORD PTR NUMLIN,AX      ;STORE # LINES
  157.     MOV    SI,OFFSET ARGPTRS+2
  158.     MOV    CX,WORD PTR NUMARGS    ;GET # OF ARGUMENTS
  159.     DEC    CX            ;-1 CAUSE OF SWITCH
  160.     JMP    SHORT GETFILES
  161. USE:
  162.         MOV     DX,OFFSET MSG4
  163.         CALL    ERRORMSG                ;TELL USER HOW TO USE
  164.         JMP     EXIT2
  165. START:    
  166.     CALL    HEAD
  167.     JMP    EXIT2
  168. GETFILES:
  169.     MOV    AX,DGROUP
  170.     MOV    DS,AX
  171.     CMP    CX,0            ;NO FILE ARGUMENTS?
  172.     JNE    GOT1
  173.     JMP    START            ;NO, JUST USE STDIN
  174. GOT1:
  175.     CMP    CX,1            ;>1 ARG?
  176.     JE    ONLY1            ;NOPE
  177.     MOV    BYTE PTR ONEFILE,0    ;>1 ARG
  178. ONLY1:
  179. ARGLUP:    MOV    BX,WORD PTR [SI]    ;BX POINTS TO FILE NAME
  180.     PUSH    CX
  181.     PUSH    SI
  182.     CALL    DOARG
  183.     POP    SI
  184.     POP    CX
  185. SKIPSW:
  186.     ADD    SI,2
  187.     LOOP    ARGLUP
  188.     JMP    EXIT2    
  189.  
  190. ;    DOARG = PROCESS 1 ARGUMENT
  191. ;    ES:BX POINTS TO IT
  192.  
  193. DOARG    PROC     NEAR
  194. NONUM:
  195.     MOV    AH,SET_DTA
  196.     MOV    DX,OFFSET DTA
  197.     INT    DOS            ;SET DTA
  198.         MOV    CX,OFFSET SPATH
  199.         MOV    DX,OFFSET PREFIX
  200.         PUSH    BX
  201.         CALL    FIXPATH                 ;PARSE PATHNAME
  202.     POP    BX
  203.     CMP    AL,TYPE_UNK
  204.     JE    BADNAME
  205.     CMP    AL,TYPE_UFN
  206.     JE    GOTNAME            ;IF UNAMBIG. FILE NAME
  207.     MOV    BYTE PTR ONEFILE,0    ;AMBIG. FILE NAME OR DIR, FLAG IT
  208.     JMP    GOTNAME
  209. BADNAME:
  210.     MOV    DX,OFFSET MSG6
  211.     CALL    ERRORMSG        ;BAD FILE NAME, SHOW MSG.
  212.     MOV    DX,BX
  213.     CALL    ERRORMSG        ;SHOW FILE THAT CAUSED IT
  214.     RET
  215. GOTNAME:
  216.         MOV     DX,OFFSET SPATH            ;POINT TO SEARCH PATH
  217.         MOV     CX,31H                  ;SET SEARCH ATTRIBUTES
  218.         MOV     AH,FIND_FIRST
  219.         INT     DOS                     ;SEARCH FOR 1ST MATCH
  220.     JB    BADNAME            ;IF NOTHING FOUND
  221. GOTFILE:
  222.     MOV    SI,OFFSET PREFIX
  223.     MOV    DI,OFFSET FILENAME
  224.     MOV    CX,65
  225.     CALL    CPYCNT            ;COPY PREFIX TO FILE NAME AREA
  226.         DEC     DI                      ;BACK UP OVER NULL
  227.         MOV     SI,(OFFSET DTA)+30         ;POINT TO FILE NAME WE FOUND
  228.         CMP     [SI],BYTE PTR '.'       ;DOES IT START WITH .? -
  229.         JNE     NOTDOT                  ;- NO
  230.     JMP     SHORT SKIPFILE         ;YES, JUST SKIP IT
  231. NOTDOT:
  232.     CALL    CPYCNT            ;COPY FILE WE FOUND AFTER PREFIX
  233.     CALL    DOFILE            ;DO 1 FILE
  234. SKIPFILE:
  235.         MOV     AH,FIND_NEXT
  236.         INT     DOS                     ;FIND NEXT MATCH, IF ANY
  237.         JC      NOMORE                  ;IF NONE
  238.         JMP     GOTFILE                 ;GOT ONE, BACK TO TOP OF LOOP
  239. NOMORE:
  240.     RET
  241. DOARG    ENDP
  242.  
  243. ;    DOFILE = PROCESS 1 FILE (NAME IN ES:FILENAME)
  244.  
  245. DOFILE  PROC    NEAR
  246.         MOV     DX,OFFSET FILENAME         ;DX POINTS TO FILE NAME
  247.         MOV     AL,READ_ACCESS
  248.         MOV     AH,DOS2_OPEN
  249.         INT     DOS                     ;TRY TO OPEN FILE
  250.         JNC     NAMEOK                  ;IF OK
  251.         JMP     SHORT BADOPN
  252. NAMEOK:
  253.         MOV     WORD PTR INHANDLE,AX    ;SAVE FILE HANDLE
  254.     CMP    BYTE PTR ONEFILE,1
  255.     JE    NOSHOW
  256.     CALL    SHOWFILE        ;SHOW FILE NAME (ONLY IF >1 SPECIFIED)
  257. NOSHOW:
  258.     CALL    HEAD            ;SHOW HEAD OF FILE
  259.     RET
  260. BADOPN:
  261.         MOV     DX,OFFSET MSG1
  262.         CALL    ERRORMSG                ;BAD OPEN, SHOW MSG.
  263.         MOV     DX,OFFSET FILENAME         ;DX POINTS TO FILE NAME
  264.         CALL    ERRORMSG                ;SHOW IT
  265.     RET
  266. DOFILE    ENDP
  267.  
  268. ;    SHOW FILE NAME
  269.  
  270. SHOWFILE PROC    NEAR
  271.     MOV    AX,"="
  272.     MOV    CX,5
  273. BARS:
  274.     CALL    WRITEBYTE
  275.     LOOP    BARS
  276.     MOV    AX,SPACE
  277.     CALL    WRITEBYTE
  278.     MOV    BX,OFFSET FILENAME
  279. SHOWF:    MOV    AL,BYTE PTR [BX]
  280.     CMP    AL,0
  281.     JE    ENDF
  282.     CALL    WRITEBYTE
  283.     INC    BX
  284.     JMP    SHOWF    
  285. ENDF:    MOV    AL,SPACE
  286.     CALL    WRITEBYTE
  287.     MOV    AL,'='
  288.     MOV    CX,5
  289. BARS2:
  290.     CALL    WRITEBYTE
  291.     LOOP    BARS2
  292.     MOV    AL,CR
  293.     CALL    WRITEBYTE
  294.     MOV    AL,LF
  295.     CALL    WRITEBYTE
  296.     RET
  297. SHOWFILE ENDP
  298.  
  299. HEAD    PROC    NEAR
  300.     MOV    CX,WORD PTR NUMLIN
  301. NEWBUF:
  302.     CALL    FILLBUF            ;FILL INPUT BUFFER
  303.     JNB    BEGIN            ;IF OK
  304.     JMP    BADREAD
  305. BEGIN:
  306.     CMP    BX,DX            ;SEE IF ANYTHING READ 
  307.     JE    CLOSEFILE        ;NO, ASSUME EOF
  308.  
  309. SHOW:   CMP     BX,DX                   ;DISPLAY TEXT - TOP OF LOOP
  310.         JGE     NEWBUF            ;IF END OF BUFFER
  311.         MOV     AL,BYTE PTR [BX]    ;GET CHAR. FROM BUFFER
  312.         INC     BX            ;BUMP POINTER
  313.     CALL    WRITEBYTE        ;WRITE CHAR. TO STDOUT
  314.         CMP     AL,CTRL$Z        ;TEST FOR ^Z
  315.     JE    CLOSEFILE        ;IF FOUND ^Z
  316.         CMP     AL,CR                   ;IS CR?
  317.         JNE     SHOW                    ;NOPE
  318.         LOOP    SHOW                    ;YES, COUNT A LINE
  319.  
  320. ;    LINE COUNT REACHED
  321.  
  322.     CMP    BX,DX            ;EXACTLY AT END OF BUFFER?
  323.     JNE    NOTEND            ;NO
  324.     CALL    FILLBUF            ;YES, JUST OUR LUCK, FILL IT AGAIN
  325.     JNB    NOTEND
  326.     JMP    SHORT BADREAD        ;IF ERROR
  327. NOTEND:
  328.         MOV     AL,BYTE PTR [BX]    ;GET CHAR. AFTER LAST CR
  329.         CMP     AL,LF
  330.         JNE     CLOSEFILE
  331.         CALL    WRITEBYTE               ;SHOW LF IF AFTER LAST CR
  332.     JMP    CLOSEFILE
  333. BADREAD:
  334.         MOV     DX,OFFSET MSG2        ;SHOW ERROR
  335.         CALL    ERRORMSG
  336.     MOV    DX,OFFSET FILENAME    
  337.     CALL    ERRORMSG        ;AND FILENAME
  338.     MOV    DX,OFFSET MSG1E
  339.     CALL    ERRORMSG        ;AND CR/LF
  340. CLOSEFILE:
  341.         MOV     BX,WORD PTR INHANDLE
  342.         MOV     AH,DOS2_CLOSE
  343.         INT     DOS                     ;CLOSE INPUT FILE
  344. EXIT1:
  345.     CALL    FLUSH            ;CLEAR OUTPUT BUFFER
  346.     RET
  347. HEAD    ENDP
  348.  
  349. ;    FILL BUFFER FROM DISK - RETURN 'C'=1 IF ERROR, BX = POINTER
  350. ;    TO START OF BUFFER, DX = POINTER TO LAST CHAR + 1
  351.  
  352. FILLBUF PROC    NEAR
  353.     PUSH    CX            ;SAVE LINE COUNT
  354.         MOV     CX,INBUFSIZE            ;CX = # BYTES TO READ
  355.         MOV     BX,WORD PTR INHANDLE    ;BX = FILE HANDLE
  356.         MOV     DX,OFFSET INBUF
  357.         MOV     AH,READ
  358.         INT     DOS                     ;FILL BUFFER FROM FILE
  359.     POP    CX            ;RESTORE LINE COUNT
  360.         JC      BAD                     ;IF ERROR
  361.         MOV     BX,OFFSET INBUF
  362.         ADD     AX,BX                   ;COMPUTE ADDR. OF LAST BYTE
  363.         MOV     DX,AX                   ;SAVE IN DX
  364.     CLC
  365. BAD:
  366.     RET
  367. FILLBUF ENDP
  368.  
  369. ;     WRITE A BYTE TO THE OUTPUT
  370. ;
  371. WRITEBYTE PROC     NEAR
  372.     PUSH    BX
  373.     PUSH    CX
  374.     PUSH    DX
  375.     MOV    BX,WORD PTR OUTNDX
  376.     MOV    BYTE PTR [BX+OUTBUF],AL
  377.     INC    BX
  378.     MOV    WORD PTR OUTNDX,BX
  379.     CMP    BX,OUTBUFSIZE
  380.     JL    NOTFUL
  381.     CALL    FLUSH
  382. NOTFUL:
  383.     POP    DX
  384.     POP    CX
  385.     POP    BX
  386.     RET
  387. WRITEBYTE ENDP
  388.  
  389. ;    FLUSH - WRITE OUTPUT BUFFER 
  390.  
  391. FLUSH    PROC    NEAR
  392.     PUSH    AX
  393.     MOV    CX,WORD PTR OUTNDX
  394.     MOV    DX,OFFSET OUTBUF
  395.     MOV    BX,1
  396.     MOV    AH,WRITE
  397.     INT    DOS        ;WRITE TO OUTPUT
  398.     POP    AX
  399.     MOV    WORD PTR OUTNDX,0
  400.     RET
  401. FLUSH    ENDP
  402.  
  403. EXIT2:
  404.         MOV     AH,EXIT
  405.         INT     DOS                     ;EXIT TO DOS
  406.  
  407.         END     ENTRY
  408.  
  409.  
  410.  
  411.